package observer

import "fmt"

// 观察者模式 示例
// 以股票市场监控系统为例，当股票价格发生变化时，需要通知多个客户端（如手机应用、网站等）进行更新。

// Observer 定义观察者接口
type Observer interface {
	// 更新价格
	Update(price float64)
}

// Subject 定义主题接口
type Subject interface {
	// 注册观察者
	RegisterObserver(observer Observer)
	// 移除观察者
	RemoveObserver(observer Observer)
	// 通知观察者
	NotifyObservers(price float64)
}

// 具体主题
type StockMarket struct {
	observers []Observer // 观察者列表
	price     float64    //股票价格
}

func (s *StockMarket) RegisterObserver(observer Observer) {
	if s.observers == nil {
		s.observers = make([]Observer, 0)
	}
	s.observers = append(s.observers, observer)
}
func (s *StockMarket) RemoveObserver(observer Observer) {
	for i, v := range s.observers {
		if v == observer {
			s.observers = append(s.observers[:i], s.observers[i+1:]...)
			break
		}
	}
}
func (s *StockMarket) NotifyObservers(price float64) {
	for _, v := range s.observers {
		v.Update(price)
	}
}

func (s *StockMarket) SetPrice(price float64) {
	s.price = price
	s.NotifyObservers(price) // 通知观察者
}

// MobileAppClient 具体观察者
type MobileAppClient struct {
	clientId string
}

func (s *MobileAppClient) Update(price float64) {
	fmt.Printf("MobileAppClient %s got price %.2f\n", s.clientId, price)
}

type WebClient struct {
	clientId string
}

func (s WebClient) Update(price float64) {
	fmt.Printf("WebClient %s got price %.2f\n", s.clientId, price)
}
